<style scoped>
* {
    box-sizing: border-box;
}

::-webkit-scrollbar {
    width: 0;
    height: 0;
    display: none;
}
</style>

<template>
    <div class="w-full h-full overflow-hidden relative" ref="el" @mouseenter="onEnter()" @mouseleave="onLeave()">
        <div ref="wrap" class="overflow-auto w-full h-full">
            <slot></slot>
        </div>
        <transition name="fade">
            <div class="absolute z-10" ref="thumbY" title="滚动条-按住拖拽Y轴" :style="thumbStyle.y" v-show="showThumb"></div>
        </transition>
        <transition name="fade">
            <div class="absolute z-10" ref="thumbX" title="滚动条-按住拖拽X轴" :style="thumbStyle.x" v-show="showThumb"></div>
        </transition>
    </div>
</template>

<script lang="ts" setup>
import {onMounted, onUnmounted, reactive, ref} from 'vue'

const {color, size} = defineProps({
    /** 滚动条颜色 */
    color: {
        type: String,
        default: 'rgba(147, 147, 153, 0.4)'
    },
    /** 滚动条厚度 */
    size: {
        type: Number,
        default: 4
    }
})

/** 组件整体节点 */
const el = ref<HTMLElement>()
/** 包围器节点 */
const wrap = ref<HTMLElement>()
/** 滚动条节点X */
const thumbX = ref<HTMLElement>()
/** 滚动条节点Y */
const thumbY = ref<HTMLElement>()

/** 滚动条节点样式 */
const thumbStyle = reactive({
    x: {
        width: '',
        height: '',
        left: '',
        bottom: '',
        transform: '',
        borderRadius: '',
        backgroundColor: color
    },
    y: {
        width: '',
        height: '',
        top: '',
        right: '',
        transform: '',
        borderRadius: '',
        backgroundColor: color
    }
})

const showThumb = ref(false)

/**
 * 初始化滚动指示器样式
 */
function initThumbStyle() {
    thumbStyle.y.top = '0px'
    thumbStyle.y.right = '0px'
    thumbStyle.y.width = `${size}px`
    thumbStyle.y.borderRadius = `${size / 2}px`

    thumbStyle.x.left = '0px'
    thumbStyle.x.bottom = '0px'
    thumbStyle.x.height = `${size}px`
    thumbStyle.x.borderRadius = `${size / 2}px`
}

/**
 * 更新滚动指示器样式
 */
function updateThumbStyle() {
    console.info('更新滚动指示器样式')
    if (wrap.value) {
        let width = (wrap.value.clientWidth / wrap.value.scrollWidth) * 100
        if (width >= 100) {
            width = 0
        }
        thumbStyle.x.width = width + '%'
        thumbStyle.x.transform = `translate3d(${wrap.value.scrollLeft / wrap.value.scrollWidth * wrap.value.clientWidth}px, 0, 0)`

        let height = wrap.value.clientHeight / wrap.value.scrollHeight * 100
        if (height >= 100) {
            height = 0
        }
        thumbStyle.y.height = height + '%'
        thumbStyle.y.transform = `translate3d(0, ${wrap.value.scrollTop / wrap.value.scrollHeight * wrap.value.clientHeight}px, 0)`
    }
}

function onEnter() {
    showThumb.value = true
    updateThumbStyle()
}

function onLeave() {
    showThumb.value = false
}

onMounted(function() {
    initThumbStyle()
    wrap.value && wrap.value.addEventListener('scroll', updateThumbStyle)
})

onUnmounted(function() {
    wrap.value && wrap.value.removeEventListener('scroll', updateThumbStyle)
})

defineExpose({
    updateThumbStyle
})
</script>
